//1. 观察者模式(Observer Pattern)
/**
 * 在JavaScript中，观察者模式通常由一个被观察者（subject）和多个观察者（observers）组成。
 * 被观察者维护一个观察者列表，当其状态发生改变时，会通知观察者进行相应的更新操作。
 * 
 * 实现步骤：
 *  定义被观察者（subject）对象，该对象维护一个观察者列表，并提供添加、删除和通知观察者的方法。
    定义观察者（observer）对象，该对象包含需要执行的更新操作。
    在观察者对象中实现更新操作的方法，该方法会在被观察者状态发生改变时被调用。
    创建被观察者对象和观察者对象，并将观察者对象添加到被观察者的观察者列表中。
    当被观察者状态发生改变时，调用通知方法，通知所有观察者进行更新操作。
 * **/ 


/**
 * @class 
 * @description 观察者1
 * */
class BinaryObserver{
	 update(i) {
       console.log("BinaryObserver",i);
   }
}

/**
 * @class 
 * @description 观察者2
 * */
class OctalObserver {
	 update(i) {
       console.log("OctalObserver ",i);
   }
}


	
/**
 * @class  
 * @description 定义被观察着对象
 * 包含观察者列表，添加、删除，通知方法 
 *  */
class Subject {  
  constructor(){ 
  	this.list=[];  
  }   
  delObjserver(obj){
  	this.list=this.list.filter(item=>item!=obj);
  } 
  addObserver(observer){
  	this.list.push(observer);
  } 
  notifyObserver(args){ 
  	 // console.log("执行通知方法",args); 
  	 this.list.forEach(item=>item.update(args));
  }   
}


let subject=new Subject(); 
//添加观察者
let a=new BinaryObserver();
subject.addObserver(a); 
let b=new OctalObserver();
subject.addObserver(b);

subject.notifyObserver("发送通知");


//移除观察者b
setTimeout(()=>{
subject.delObjserver(b);
},4000)


/*
B. 观察者模式的优缺 
优：建立一套触发机制，解耦目标与观察者，符合开闭原则 
缺：若观察者与目标直接按存在循环依赖，可能导致系统崩溃

C. 观察者模式适用场景 
一个对象的改变将导致其他一个或多个对象也发生改变，但不知道具体有多少对象将发生改变；
或者在系统中需要创建一个触发链。观察者模式可以用来实现MVC模式，
观察者模式中的观察目标就是MVC模式中的模型(Model)，而观察者就是MVC中的视图(View)，
控制器(Controller)充当两者之间的中介者(Mediator)。当模型层的数据发生改变时，
视图层将自动改变其显示内容。
**/